import React, { FC, useEffect, useRef, useState } from 'react'
import { TableProps, ColumnType } from './interface'
function classNames(...names: (string | undefined)[]) {
  const currentNames: string[] = []
  names.forEach((name: (string | undefined)) => {
    if (name) currentNames.push(name)
  })
  return currentNames.join(' ')
}

function getFixedColumns(columns: ColumnType[]) {
  const total: number = columns.length
  const leftFixedColumns: number[] = []
  const rightFixedColumns: number[] = []
  if (columns[0].fixed) {
    // eslint-disable-next-line no-plusplus
    for (let i = 0; i < total; i++) {
      if (columns[i].fixed) {
        leftFixedColumns.push(i)
      } else {
        break
      }
    }
  }
  if (columns[total - 1].fixed) {
    // eslint-disable-next-line no-plusplus
    for (let i = total - 1; i >= 0; i--) {
      if (columns[i].fixed) {
        if (!leftFixedColumns.includes(i)) rightFixedColumns.push(i)
      } else {
        break
      }
    }
  }
  return [leftFixedColumns, rightFixedColumns]
}

function renderCols(columns: ColumnType[]) {
  return columns.map((column: ColumnType, index: number) => {
    const width: number = column.width || 50
    return (
      <col
        key={index}
        style={{ width: width, minWidth: width }}
      />
    )
  })
}

function renderCells(columns: ColumnType[], leftFixedColumns: number[], rightFixedColumns: number[], record: any) {
  return columns.map((column: ColumnType, index: number) => {
    const align: any = column.align || undefined
    // eslint-disable-next-line no-nested-ternary
    const fixed: string = leftFixedColumns.includes(index) ? 'left' : (rightFixedColumns.includes(index) ? 'right' : '')
    const className: string = classNames('st-table-cell', column.className, fixed ? ('st-table-cell-fix-' + fixed) : '')
    const rawValue: any = (column.dataKey && column.dataKey in record) ? record[column.dataKey] : undefined
    let value: any
    if (column.render) {
      value = column.render(rawValue, record, index)
    } else {
      value = (rawValue === undefined || rawValue === null) ? '' : String(rawValue)
    }
    return (
      <td
        key={index}
        className={className}
        style={{ textAlign: align }}
      >
        {value}
      </td>
    )
  })
}
const ScrollableTable: FC<TableProps> = ({ dataSource, pageSize, columns = [] }, props) => {
  const style: React.CSSProperties = props.style || {}
  const maxHeight: string = props.width ? (props.height + 'px') : 'unset'
  const [data, setData] = useState<any[]>([])
  const [pageNum] = useState<number>(props?.pageNum || 1)
  const [ps, setPs] = useState<number>(props?.pageSize || 55)  
  let maxWidth: number = 0
  if (props.width) style.width = props.width
  if (columns.length === 0) {
    columns.push({
      dataKey: 'key'
    })
  }
  columns.forEach((column: ColumnType) => {
    const width: number = column.width || 50
    maxWidth += width
  })

  const fixedColumns: number[][] = getFixedColumns(columns)
  const leftFixedColumns: number[] = fixedColumns[0]
  const rightFixedColumns: number[] = fixedColumns[1]

  const tableBody: any = useRef()
  const handleScroll = (target: any) => {
    const scrollLeft: number = target.scrollLeft
    const tableHeaders: any = target.parentElement.getElementsByClassName('st-table-header')
    if (tableHeaders.length > 0) {
      tableHeaders[0].scrollLeft = scrollLeft
    }
  }
  // const showLoading = () => dataSource && dataSource?.length > 0 && ps * pageNum < dataSource.length
  const onscroll = (e: any) => {
    if (!dataSource?.length) return
    const top = e.target.scrollTop
    // if (top < 100 && pageNum > 1) {
    //   const d = dataSource.slice((pageNum - 1) * ps, pageNum * ps)
    //   setData([...d, ...data])
    // }
    const bottom = e.target.scrollHeight - e.target.offsetHeight - top
    if (bottom < 100 && pageNum * ps < dataSource.length) {
      const d = dataSource.slice(pageNum * ps, (pageNum + 1) * ps)
      setData([...d, ...data])
    }
  }
  useEffect(() => {
    pageSize && setPs(pageSize)
  }, [pageSize])
  useEffect(() => {
    setData(dataSource?.slice((pageNum - 1) * ps, ps * pageNum) || [])
    document.getElementById('st-table-container')?.scroll(0, 0)
  }, [dataSource])
  useEffect(() => {
  }, [data])
  return (
    <div
      id={'st-table-container'}
      className={classNames('st-table-container', props.className)}
      style={style}
      onScroll={ onscroll }
    >
      <div className="st-table-header">
        <table>
          <colgroup>
            {
              renderCols(columns)
            }
          </colgroup>
          <thead className="st-table-thead">
            <tr>
              {
                columns.map((column: ColumnType, index: number) => {
                  const align: any = column.align || undefined
                  const title: React.ReactNode = column.title || ''
                  // eslint-disable-next-line no-nested-ternary
                  const fixed: string = leftFixedColumns.includes(index) ? 'left' : (rightFixedColumns.includes(index) ? 'right' : '')
                  const fixedClassName: string = fixed ? ('st-table-cell-fix-' + fixed) : ''
                  return (
                    <th
                      key={index}
                      className={classNames('st-table-cell', fixedClassName, column.className)}
                      style={{ textAlign: align }}
                    >
                      {title}
                    </th>
                  )
                })
              }
            </tr>
          </thead>
        </table>
      </div>
      <div
        ref={tableBody}
        className="st-table-body"
        style={{ maxHeight: maxHeight }}
        onScroll={(e: any) => handleScroll(e.currentTarget)}
      >
        <table style={{ width: maxWidth, minWidth: '100%' }}>
          <colgroup>
            {
              renderCols(columns)
            }
          </colgroup>
          <tbody className="st-table-tbody">
            {
              data.map((record: any, index: number) => (
                <tr key={index} className="st-table-row">
                  {
                    renderCells(columns, leftFixedColumns, rightFixedColumns, record)
                  }
                </tr>
              ))
            }
          </tbody>
        </table>
      </div>
    </div>
  )
}

export default ScrollableTable
